<template>
	<el-container class="my-container" :key="selectKey">
		<el-header>
			<el-form :inline="true">
				<el-form-item label="">
					<el-select v-model="form.lang" @change="langChange">
						<el-option
							v-for="item in langsList"
							:key="item.language"
							:label="item.langText"
							:value="item.language"
						>
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item>
					<el-button
						type="primary"
						icon="el-icon-position"
						@click="runBtn"
						:loading="runLoading"
						:disabled="runLoading"
						>运行</el-button
					>
				</el-form-item>
			</el-form>
		</el-header>
		<div class="container-result">
			<el-row class="container-row-code">
				<el-col :span="24" style="height: 100%">
					<textarea ref="editorArea" v-model="curCode"></textarea>
				</el-col>
			</el-row>
			<el-row class="container-row-result">
				<el-col :span="24">
					<el-input
						type="textarea"
						class="container-row-result-text"
						v-model="resultCode"
						:autosize="{ minRows: 10, maxRows: 10 }"
					></el-input>
				</el-col>
			</el-row>
		</div>
	</el-container>
</template>

<script>
import { markRaw } from "vue";
import CodeMirror from "codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/keymap/sublime"; //sublime编辑器效果
import "codemirror/theme/dracula.css"; // 配置里面也需要theme设置为monokai
import "codemirror/theme/solarized.css"; // 配置里面也需要theme设置为monokai
import "codemirror/mode/vue/vue.js"; // 配置里面也需要mode设置为vue
import "codemirror/addon/selection/active-line"; //光标行背景高亮，配置里面也需要styleActiveLine设置为true
import "codemirror/addon/hint/show-hint.css"; // 配置里面也需要mode设置为vue
// 语言引入
import "codemirror/mode/clike/clike.js";
import "codemirror/mode/csharp/csharp.js";
import "codemirror/mode/java/java.js";
import "codemirror/mode/python/python.js";
import "codemirror/mode/php/php.js";
import "codemirror/mode/css/css.js";
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/sql/sql.js";
import "codemirror/mode/htmlmixed/htmlmixed.js";

// <!-- 自动提示 -->
import "codemirror/addon/hint/show-hint.js";
import "codemirror/addon/hint/sql-hint.js";
import "codemirror/addon/hint/javascript-hint.js";
//   <!-- csharp 自动提示 -->
import "codemirror/addon/hint/CsCompleter.js";
import "codemirror/addon/hint/csharp-hint.js";
//   <!-- java 自动提示 -->
import "codemirror/addon/hint/JavaCompleter.js";
import "codemirror/addon/hint/java-hint.js";
//   <!-- python 自动提示 -->
import "codemirror/addon/hint/pyton-hint.js";
//   <!-- html 自动提示 -->
import "codemirror/addon/hint/html-hint.js";
//   <!-- xml 自动提示 -->
import "codemirror/addon/hint/xml-hint.js";
//   <!-- css 自动提示 -->
import "codemirror/addon/hint/css-hint.js";
//   <!-- sql 自动提示 -->
import "codemirror/addon/hint/sql-hint.js";

export default {
	components: {},
	data() {
		return {
			selectKey: 1,
			extensions: [],
			cmOptions: {
				autoCloseBrackets: true, // 自动闭合符号
				lineNumbers: true, //是否在编辑器左侧显示行号
				matchBrackets: true, // 是否添加匹配括号高亮
				mode: this.lang, //C++
				indentUnit: 4, // 缩进单位为4
				lineWrapping: true, //自动换行
				autofocus: true,
				indentWithTabs: true, //
				smartIndent: true, //自动缩进，设置是否根据上下文自动缩进（和上一行相同的缩进量）。默认为true。
				styleActiveLine: true, // 当前行背景高亮
				gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
				theme: "solarized", // 编辑器主题 dracula sqlTheme
				extraKeys: { Ctrl: "autocomplete" },
				hintOptions: {
					completeSingle: false,
				},
				tabSize: 4,
				spellcheck: true,
			},
			runLoading: false,
			curCode: "",
			editor: null,
			lang: "",
			form: {
				lang: "java",
				questionKey: "",
			},
			resultCode: "",
			result: {
				key: "",
				timer: null,
			},
			langsList: [],
		};
	},
	computed: {},
	beforeUnmount() {
		this.result.timer = null;
		clearTimeout(this.result.timer);
	},
	mounted: function () {
		this.init();
	},
	methods: {
		init() {
			var that = this;
			this.$nextTick(() => {
				this.editor = markRaw(
					CodeMirror.fromTextArea(
						this.$refs.editorArea,
						this.cmOptions
					)
				);
				this.editor.setSize("100%", "100%");
				this.editor.on("inputRead", (cm, change) => {
					var val = change.text;
					console.log(val);
					if (val == " " || val == ";" || val == "(" || val == "{")
						return;
					that.editor.showHint();
				});
			});
		},
		async setEditorValue(data, mode) {
			this.$nextTick(() => {
				this.editor.setValue(data);
				if (mode == "c++") {
					mode = "c";
				}
				this.lang = "text/x-" + mode;
				this.editor.setOption("mode", this.lang);
				setTimeout(() => {
					this.editor.refresh();
				}, 200);
			});
		},
		async runBtn() {
			this.runLoading = true;
			var code = this.editor.getValue();
			var lan = this.form.lang;
			var res = await this.$API.webide.run.post({
				code: code,
				lan: lan,
				questionKey: this.form.questionKey,
			});

			console.log("运行结果：", res);
			//获取到查询结果的key
			this.result.key = res.data;
			//然后定时轮询结果
			if (this.result.key != null && this.result.key != "") {
				await this.getResult();
			}
			//this.resultCode = res.data.stdOutput;
		},
		async getResult() {
			var that = this;
			this.result.timer = setTimeout(async () => {
				var res = await this.$API.webide.result.get(this.result.key);
				console.log("getResult is :", res);
				if (res.data == null) {
					//继续轮询
					await that.getResult();
				} else {
					that.runLoading = false;
					that.resultCode = "";
					//渲染结果
					that.resultCode +=
						"[评测状态]:" + (res.data.statusMsg ?? "") + " \n";
					that.resultCode +=
						"[标准输出]:" + (res.data.stdOutput ?? "") + " \n";
					that.resultCode +=
						"[错误输出]:" + (res.data.stdError ?? "") + " \n";

					that.resultCode +=
						"[时间消耗]:" +
						(res.data.timeConsumption ?? "") +
						"  \n";
					that.resultCode +=
						"[内存消耗]:" +
						(res.data.memoryConsumption ?? "") +
						"  \n";
					clearTimeout(that.result.timer);
				}
			}, 2000);
		},
		async renderLangs(questionKey) {
			// this.selectKey = this.selectKey++;
			var res = await this.$API.question.detail.get(questionKey);
			this.langsList = res.data.languages;
			this.form.questionKey = questionKey;
			console.log("获得到的结果为：", this.langsList);
			if (this.langsList.length > 0) {
				var item = this.langsList[0];
				if (item != null) {
					this.form.lang = item.language;
					this.curCode = item.examples;
					this.setEditorValue(this.curCode, item.language);
				}
			}
		},
		async langChange(data) {
			this.langsList.forEach(async (item) => {
				if (item.language == data) {
					this.lang = data;
					await this.setEditorValue(item.examples, data);
					return;
				}
			});
			console.log("退出循环");
		},
	},
};
</script>
<style scoped>
.the-code-editor-container,
.code-editor-result {
	width: 100%;
	min-height: 100px;
	height: 100%;
	overflow: auto;
}
.code-editor-result {
	background-color: white;
}
.container-row {
	width: 100%;
	height: 100%;
	font-size: 15px !important;
}
.my-container {
	width: 100%;
	height: 100%;
}
.container-result {
	height: calc(100% - 60px);
	width: 100%;
}
.container-row-code {
	height: 70%;
}
.container-row-result {
	height: calc(30% - 20px);
}

.container-row-result .el-textarea {
	height: 100% !important;
}
.container-row-result-text > textarea {
	height: 100% !important;
}
</style>
